/**
 * This software is copyrighted by Bosch Connected Devices and Solutions GmbH, 2016.
 * The use of this software is subject to the XDK SDK EULA
 */
/**
 * @defgroup MAX44009 MAX44009
 * @ingroup Device
 *
 * @{
 * @brief  MAX44009 lib
 *  \tableofcontents
 *  \section intro_sec MAX44009
 *  Provides APIs to  configure and read the Light sensor
 */
/* header definition ******************************************************** */
#ifndef BCDS_MAX44009_H_
#define BCDS_MAX44009_H_

/* public interface declaration ********************************************* */
#include "BCDS_Retcode.h"

/* public type and macro definitions */

/** enum to represent Ambient light sensor supported brightness configurations*/
enum MAX44009_ConfigBrightness_E
{
    MAX44009_NORMAL_BRIGHTNESS, /**< normal brightness */
    MAX44009_HIGH_BRIGHTNESS, /**< high brightness */
    MAX44009_OUT_OF_BRIGHTNESS /**< Unsupported Brightness Range */
};
typedef enum MAX44009_ConfigBrightness_E MAX44009_ConfigBrightness_T, *MAX44009_ConfigBrightnessPtr_T;

/** enum to represent enabled  or disabled of Sensor get or read operations*/
enum MAX44009_ConfigStatus_E
{
    MAX44009_DISABLE, /**< indicates the disabled state */
    MAX44009_ENABLE, /**< indicates the enabled state */
};
typedef enum MAX44009_ConfigStatus_E MAX44009_ConfigStatus_T;

/** enum values to represent the interrupt status */
enum MAX44009_IntrpStatus_E
{
    MAX44009_NO_INTR_EVENT_DETECTED, /**< no interrupt event triggered */
    MAX44009_INTR_EVENT_DETECTED, /**<interrupt event detected */
};
typedef enum MAX44009_IntrpStatus_E MAX09_IntrpStatus_T;

/** enum values to represent the supported integration time values by the ambient light sensor */
enum MAX44009_IntegrationTime_E
{
    MAX44009_800MS, /**< 800 ms integration time(time taken for capturing lux intensity) */
    MAX44009_400MS, /**< 400 ms integration time */
    MAX44009_200MS, /**< 200 ms integration time */
    MAX44009_100MS, /**< 100 ms integration time */
    MAX44009_50MS, /**< 50 ms integration time */
    MAX44009_25MS, /**< 25 ms integration time */
    MAX44009_12P5MS, /**< 12.5 ms integration time */
    MAX44009_6P5MS, /**< 6.5 ms integration time */
    MAX4409_OUT_OF_TIME /**< Out of Integration Time Supported Range */
};
typedef enum MAX44009_IntegrationTime_E MAX44009_IntegrationTime_T, *MAX44009_IntegrationTimePtr_T;

/** structure to hold the configuration parameters for manual mode*/
struct MAX44009_ManualModeConfig_S
{
    MAX44009_IntegrationTime_T time;
    MAX44009_ConfigBrightness_T brightness;
};
typedef struct MAX44009_ManualModeConfig_S MAX44009_ManualModeConfig_T;

/** enum values to represent the Manual , continuous interrupt configuration modes and represents the interrupt status */
enum MAX09_ConfigMode_E
{
    MAX44009_DISABLE_MANUAL_MODE = 0, /**< Manual mode disable */
    MAX44009_ENABLE_MANUAL_MODE, /**< Manual mode enable */
    MAX44009_DISABLE_CONTINOUS_MODE = 0, /**< Continous mode disable */
    MAX44009_ENABLE_CONTINOUS_MODE, /**< Continous mode enable */
    MAX44009_DISABLE_INTERRUPT = 0, /**< interrupt disable */
    MAX44009_ENABLE_INTERRUPT, /**< enable interrupt */
    MAX44009_NO_INTR_TRIGGER_EVENT = 0, /**<  no interrupt triggered */
    MAX44009_INTR_TRIGGER_EVENT, /**< interrupt triggered */
};
typedef enum MAX09_ConfigMode_E MAX44009_ConfigMode_T, *MAX44009_ConfigModePtr_T;

/** enum to represent MAX44009 supported register address*/
enum MAX44009_Registers_E
{
    MAX44009_INTERRUPT_STATUS_REG = 0x00, /**< interrupt status register */
    MAX44009_INTERRUPT_ENABLE_REG, /**< interrupt enable register */
    MAX44009_CONFIGURATION_REG, /**< configuration register */
    MAX44009_LUX_HIGH_BYTE_REG, /**< lux high byte register */
    MAX44009_LUX_LOW_BYTE_REG, /**< lux low byte register */
    MAX44009_UPPER_THRESHOLD_REG, /**< upper threshold high byte register */
    MAX44009_LOWER_THRESHOLD_REG, /**< lower threshold high byte register */
    MAX44009_THRESHOLD_TIMER_REG, /**< threshold timer register */
    MAX44009_THRESHOLD_UNSUPPORTED /**< Threshold Unsupported Range */
};
typedef enum MAX44009_Registers_E MAX44009_Registers_T;

/**
 * @brief Sensor register write function prototype
 *
 * @param [in] dev_addr device address
 *
 * @param [in] reg_addr register address
 *
 * @param [in] data_p  data
 *
 * @param [in] wr_len  length of the data
 *
 * @returns int8_t
 *            0  Success
 *           -1  Fail
 */
typedef int8_t (*MAX44009_writeReg)(uint8_t dev_addr, uint8_t reg_addr,
    uint8_t *data_p, uint8_t wr_len);

/**
 * @brief Sensor register Read function prototype
 *
 * @param [in] dev_addr device address
 *
 * @param [in] reg_addr register address
 *
 * @param [in] data_p  data
 *
 * @param [in] wr_len  length of the data
 *
 * @returns int8_t
 *            0  Success
 *           -1  Fail
 */
typedef int8_t (*MAX44009_readReg)(uint8_t dev_addr, uint8_t reg_addr,
    uint8_t *data_p, uint8_t r_len);

/**
 * @brief Delay function prototype
 *
 * @param [in] timeInMs time in milliseconds
 *
 */
typedef void (*MAX44009_delayFunc)(uint32_t timeInMs);

/** structure to hold the initialization parameters of the sensor */
struct MAX44009_Init_S
{
    uint8_t dev_add; /**< I2c slave address */
    MAX44009_writeReg writeFunc; /**< I2C bus write function */
    MAX44009_readReg readFunc; /**< I2C bus read function */
    MAX44009_delayFunc delayFunc; /**< Delay function */
};
typedef struct MAX44009_Init_S MAX44009_Init_T, *MAX44009_InitPtr_T;

/* public function prototype declarations */

/**
 * @brief
 *      The function to initialize the ambient light sensor.
 *      It initializes and preserves the i2c address and i2c bus read , write functions for further communication
 *      between the sensor and the controller
 *
 * @param [in] configParams configuration parameters
 *
 * @retval      Retcode_T       The return value consist of (First 1 MSByte represents Package ID, Next  Byte represents Severity and Last 2 LSBytes represents error code)
 *
 */
Retcode_T MAX44009_init(MAX44009_InitPtr_T configParams);

/**
 * @brief
 *      The function to set the CDR value of the Configuration register
 *      Api to configure the desired photodiode current that goes to ADC
 *
 * @param [in] cdr  CDR value(from the provided enum value)
 *
 * @retval      Retcode_T       The return value consist of (First 1 MSByte represents Package ID, Next  Byte represents Severity and Last 2 LSBytes represents error code)
 *
 * @note reflects the configured value only if Manual mode is enabled
 */
Retcode_T MAX44009_setCdr(MAX44009_ConfigBrightness_T cdr);

/**
 * @brief The function to get the configured CDR value
 *
 * @param [out] cdr  configured cdr value
 *
 * @retval      Retcode_T       The return value consist of (First 1 MSByte represents Package ID, Next  Byte represents Severity and Last 2 LSBytes represents error code)
 *
 */
Retcode_T MAX44009_getCdr(uint8_t * cdr);

/**
 * @brief  The function to get the configuration register value
 *
 * @param [out] configuredVal  the read configuration register value
 *
 * @retval      Retcode_T       The return value consist of (First 1 MSByte represents Package ID, Next  Byte represents Severity and Last 2 LSBytes represents error code)
 *
 */
Retcode_T MAX44009_getConfigurationReg(uint8_t *configuredVal);

/**
 * @brief The function to configure the integration time of the sensor
 *
 * @param [in]  time integration time
 *
 * @retval      Retcode_T       The return value consist of (First 1 MSByte represents Package ID, Next  Byte represents Severity and Last 2 LSBytes represents error code)
 *
 * @note reflects the configured value only if Manual mode is enabled
 */
Retcode_T MAX44009_setIntegrationTime(MAX44009_IntegrationTime_T time);

/**
 * @brief The function to get the configured integration time value
 *
 * @param [out] time configured time
 *
 * @retval      Retcode_T       The return value consist of (First 1 MSByte represents Package ID, Next  Byte represents Severity and Last 2 LSBytes represents error code)
 *
 */
Retcode_T MAX44009_getIntegrationTime(uint8_t * time);

/**
 * @brief  The function to get the light sensor values in LUX
 *
 * @param [out] sensorData raw sensor data represented in the  16 bit output format [0 0 0 0 E3 E2 E1 E0 M7 M6 M5 M4 M3 M2 M1 M0] from [bit 15 to bit 0].
 *             M7-M0:Mantissa and E3-E0:Exponent
 *
 * @retval      Retcode_T       The return value consist of (First 1 MSByte represents Package ID, Next  Byte represents Severity and Last 2 LSBytes represents error code)
 *
 */
Retcode_T MAX44009_getSensorData(uint16_t *sensorData);

/**
 * @brief  The function to convert the Raw sensor value to Milli Lux
 *
 * @param [in] sensorData  raw sensor value
 *
 * @param [out] sensorData  sensor value in milli lux
 */
uint32_t MAX44009_getDataInMilliLux(uint16_t sensorData);

/**
 * @brief Function used to set the upper threshold level of the sensor
 *
 * @param [in] thresholdVal  Threshold value that to be configured
 *
 * @retval      Retcode_T       The return value consist of (First 1 MSByte represents Package ID, Next  Byte represents Severity and Last 2 LSBytes represents error code)
 *
 */
Retcode_T MAX44009_setUpperThreshold(uint8_t thresholdVal);

/**
 * @brief Function to set the lower threshold level of the sensor
 *
 * @param [in] thresholdVal threshold value that to be configured
 *
 * @retval      Retcode_T       The return value consist of (First 1 MSByte represents Package ID, Next  Byte represents Severity and Last 2 LSBytes represents error code)
 *
 */
Retcode_T MAX44009_setLowerThreshold(uint8_t thresholdVal);

/**
 * @brief Function  to get the upper threshold value
 *
 * @param [out] thresholdVal  the upper threshold value
 *
 * @retval      Retcode_T       The return value consist of (First 1 MSByte represents Package ID, Next  Byte represents Severity and Last 2 LSBytes represents error code)
 *
 */
Retcode_T MAX44009_getUpperThreshold(uint8_t *thresholdVal);

/**
 * @brief Function  to get the Lower threshold value
 *
 * @param [out] thresholdVal  the Lower threshold value
 *
 * @retval      Retcode_T       The return value consist of (First 1 MSByte represents Package ID, Next  Byte represents Severity and Last 2 LSBytes represents error code)
 *
 */
Retcode_T MAX44009_getLowerThreshold(uint8_t *thresholdVal);

/**
 * @brief Function used to set the threshold timer
 *
 * @param [in] thresholdTimerVal threshold timer value(100ms) that to be configured
 *
 * @retval      Retcode_T       The return value consist of (First 1 MSByte represents Package ID, Next  Byte represents Severity and Last 2 LSBytes represents error code)
 *
 */
Retcode_T MAX44009_setThresholdTimer(uint8_t thresholdTimerVal);

/**
 * @brief Function to get the threshold timer register value
 *
 * @param [out] thresholdTimerVal  threshold timer value in 100ms
 *
 * @retval      Retcode_T       The return value consist of (First 1 MSByte represents Package ID, Next  Byte represents Severity and Last 2 LSBytes represents error code)
 *
 */
Retcode_T MAX44009_getThresholdTimer(uint8_t * thresholdTimerVal);

/**
 * @brief The function to set Continuous mode
 *        MAX44009_DISABLE_CONTINOUS_MOD(default mode): the IC measures lux intensity only once every 800ms regardless of
 *        integration time
 *        MAX44009_ENABLE_CONTINOUS_MODE : The IC continuously measures lux intensity. That is, as soon
 *        as one reading is finished, a new one begins. If integration time is 6.25ms, readings are taken every 6.25ms
 *        If integration time is 800ms,readings are taken every 800ms
 *
 * @param [in] configParam value of the continuous mode
 *
 * @retval      Retcode_T       The return value consist of (First 1 MSByte represents Package ID, Next  Byte represents Severity and Last 2 LSBytes represents error code)
 *
 */
Retcode_T MAX44009_setContinousModeReg(MAX44009_ConfigMode_T configParam);

/**
 * @brief The function to get the  Continuous mode
 *
 * @param [out] configParams gets the continuous mode value
 *
 * @retval      Retcode_T       The return value consist of (First 1 MSByte represents Package ID, Next  Byte represents Severity and Last 2 LSBytes represents error code)
 *
 */
Retcode_T MAX44009_getContinousModeReg(uint8_t* configParams);

/**
 * @brief The function to set Manual mode
 * MAX44009_ENABLE_MANUAL_MODE  : CDR, and TIM[2:0] bits can be programmed,
 * MAX44009_DISABLE_MANUAL_MODE((default mode)) : CDR, TIM[2:0] bits are automatically determined by the internal autoranging circuitry of the IC
 *
 * @param [in] configParam      value of the manual mode
 *
 * @retval      Retcode_T       The return value consist of (First 1 MSByte represents Package ID, Next  Byte represents Severity and Last 2 LSBytes represents error code)
 *
 */
Retcode_T MAX44009_setManualModeReg(MAX44009_ConfigMode_T configParam);

/**
 * @brief The function to get Manual mode
 *
 * @param [out] configParams  value of the manual mode
 *
 * @retval      Retcode_T       The return value consist of (First 1 MSByte represents Package ID, Next  Byte represents Severity and Last 2 LSBytes represents error code)
 *
 */
Retcode_T MAX44009_getManualModeReg(uint8_t* configParams);

/**
 * @brief The function to get the interrupt status
 *
 * @param [out] status the interrupt triggered event status
 *
 * @retval      Retcode_T       The return value consist of (First 1 MSByte represents Package ID, Next  Byte represents Severity and Last 2 LSBytes represents error code)
 *
 */
Retcode_T MAX44009_getInterptStatus(uint8_t* status);

/**
 * @brief The function to configure interrupt
 *
 * @param [in] configParam interrupt configured value
 *
 * @retval      Retcode_T       The return value consist of (First 1 MSByte represents Package ID, Next  Byte represents Severity and Last 2 LSBytes represents error code)
 *
 */
Retcode_T MAX44009_setIntrptReg(MAX44009_ConfigMode_T configParam);

/**
 * @brief The function to get interrupt register value
 *
 * @param [out] configParam configured value
 *
 * @retval      Retcode_T       The return value consist of (First 1 MSByte represents Package ID, Next  Byte represents Severity and Last 2 LSBytes represents error code)
 *
 */
Retcode_T MAX44009_getIntrptReg(MAX44009_ConfigModePtr_T configParam);

/**
 * @brief The function to get a register value
 *
 * @param [in] regAddress    register address that to be read
 *
 * @param [out] value configured value
 *
 * @retval      Retcode_T       The return value consist of (First 1 MSByte represents Package ID, Next  Byte represents Severity and Last 2 LSBytes represents error code)
 *
 */
Retcode_T MAX44009_getRegister(MAX44009_Registers_T regAddress, uint8_t * value);

/**
 * @brief The function to set a register value
 *
 * @param [in] regAddress register address that to be write
 *
 * @param [in] value  the value that to be configured
 *
 * @retval     Retcode_T       The return value consist of (First 1 MSByte represents Package ID, Next  Byte represents Severity and Last 2 LSBytes represents error code)
 *
 */
Retcode_T MAX44009_setRegister(MAX44009_Registers_T regAddress, uint8_t value);


Retcode_T MAX44009_getConfigurationReg(uint8_t *configuredVal);

/**
 * @brief The function to deinitialize the sensor
 */
void MAX44009_deInit(void);

/* public global variable declarations */

/* inline function definitions */

#endif /* BCDS_MAX44009_H_ */

/** @} */

/** ************************************************************************* */
